// 6.3.3 返回数组指针
/**
 * 因为数组不能被拷贝，所以函数不能返回数组。不过，函数可以返回数组的指针或引用（参见3.5.1节，第102页）。
 * 虽然从语法上来说，要想定义一个返回数组的指针或引用的函数比较烦琐，但是有一些方法可以简化这一任务，其中最直接的方法是使用类型别名。
 */
#include <iostream>
#include <initializer_list>
#include <iterator>
#include <vector>
using std::begin, std::end;
using std::cin, std::cout, std::endl;
using std::initializer_list;
using std::string;
using std::vector;

// 使用类型别名简化数组定义
typedef int arrT[10];  // arrT是个类型别名，他表示的类型是含有10个整数的数组
using arrT1 = int[10]; // arrT1等价于arrT
arrT *func(int i);     // func返回一个指向含有10个整数的数组的指针；或写成 arrT *func(int i);

// 声明一个返回数组指针的函数
// 要想在声明func时不使用类型别名，我们必须牢记被定义的名字后面数组的维度
int arr[10];          // arr是含有10个整数的数组
int *p1[10];          // p1是个数组，它含有10个指向整型的指针
int (*p2)[10] = &arr; // p2是个指针，它指向含有10个整数的数组

// 声明一个返回数组指针的函数
int (*func(int a, int b))[10]; // 形参列表后的[10]代表这个返回的指针指向数组，数组的维度是10
// int *func1(int a,int b)[10]; // 代表func1这个函数的返回类型是数组，该数组包含10个指向整数的指针。
//  但int *func1(int a,int b)[10];这种形式是错误的，因为数组不能作为函数的返回值。

// 使用尾置返回类型
// 任何函数的定义都能使用尾置返回，但是这种形式对于返回类型比较复杂的函数最有效.
// 比如返回类型是数组的指针或者数组的引用。尾置返回类型跟在形参列表后面并以一个->符号开头。
// 为了表示函数真正的返回类型跟在形参列表之后，我们在本应该出现返回类型的地方放置一个auto
auto func2(int a, int b) -> int (*)[10]; // func2等价于func

// 使用decltype
// 还有一种情况，如果我们知道函数返回的指针将指向哪个数组，就可以使用decltype关键字声明返回类型
int odd[] = {1, 3, 5, 7, 9};
int even[] = {2, 4, 6, 8, 10};
decltype(odd) *arrPtr(int i) // 返回一个指针，该指针指向含有5个整数的数组
{
    return (i % 2) ? &odd : &even; // 返回一个指向数组的指针，即数组指针
}

int main(int argc, char const *argv[])
{

    return 0;
}
